/*
    Estado        Metodo
    P           insertarCliente() - Diego
    P           modificarCliente() - Diego
    P           obtenerClientePorEmail - Diego
    P           obtenerCliente - Diego
    P           listarLocalidades - Diego
    P           listarProvincias - Diego
    P           listarPaises - Diego
 */

package dal;

import bd.BoundParam;
import bd.ConexionAvw;

import excepciones.AvwException;

import java.util.Date;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.logging.Level;
import java.util.logging.Logger;

import negocio.ArticuloWeb;
import negocio.CampaniaWeb;
import negocio.Cliente;
import negocio.MicrositioWeb;
import negocio.Ubicacion;
import util.Recurso;

import util.Utiles;

public class ClienteDAL {
    
    
    
    static final Logger logger = Utiles.iniciarLogger("ClienteDAL", false);
    public ClienteDAL() {
    }
    
    /**
     * Obtiene el cliente cuyo email es el pasado por parametro.
     * @return objeto Cliente.
     * @param  cliente Cliente (con el email).
     */
    public static Cliente obtenerClientePorEmail(Cliente cliente) throws AvwException {
        StringBuilder sql = new StringBuilder();
        ResultSet rs;
        ConexionAvw conexion = new ConexionAvw();
        ArrayList params = new ArrayList();
        int pos = 0;
        
        sql.append("SELECT ");
        sql.append("c.cli_codigo, ");
        sql.append("c.cli_nombre, ");
        sql.append("c.cli_razon_social, ");
        sql.append("c.cli_direccion, ");
        sql.append("c.cli_piso, ");
        sql.append("c.cli_departamento, ");
        sql.append("c.cli_localidad, ");
        sql.append("c.cli_provincia, ");
        sql.append("c.cli_pais, ");
        sql.append("c.cli_codigo_postal, ");
        sql.append("c.cli_mail, ");
        sql.append("c.cli_ingresos_brutos, ");
        sql.append("c.cli_tipo_iva, ");
        sql.append("c.cli_cuit, ");
        sql.append("cw.clw_email, ");
        sql.append("cw.clw_contrasenia ");
        sql.append("FROM clientes c, cliente_web cw ");
        sql.append("WHERE c.cli_codigo = cw.cli_codigo ");
        sql.append("AND cw.clw_email LIKE ? ");
        params.add(new BoundParam(++pos,cliente.getCliEmail(),java.sql.Types.VARCHAR));
        
        try {
            logger.info(sql.toString());
            conexion.abrirConexion();
            rs = conexion.getPreparedStatementResultSet(sql, params);
            
            rs.next();
            cliente.setCliCodigo(rs.getString("cli_codigo"));
            cliente.setCliNombre(rs.getString("cli_nombre"));
            cliente.setCliRazonSocial(rs.getString("cli_razon_social"));
            cliente.setCliDireccion(rs.getString("cli_direccion"));
            cliente.setCliPiso(rs.getString("cli_piso"));
            cliente.setCliDepartamento(rs.getString("cli_departamento"));
            cliente.setCliLocalidad(new Ubicacion(rs.getString("cli_localidad")));
            cliente.setCliProvincia(new Ubicacion(rs.getString("cli_provincia")));
            cliente.setCliPais(new Ubicacion(rs.getString("cli_pais")));
            cliente.setCliCodigoPostal(rs.getString("cli_codigo_postal"));
            cliente.setCliIngresosBrutos(rs.getString("cli_ingresos_brutos"));
            cliente.setCliTipoIva(rs.getString("cli_tipo_iva"));
            cliente.setCliCuit(rs.getString("cli_cuit"));
            cliente.setCliEmail(rs.getString("clw_email"));
            cliente.setCliContrasenia(rs.getString("clw_contrasenia"));
            
        } catch (SQLException e) {
            logger.info("Puede no existir el cliente");
            throw new AvwException(e, "clienteInexistente");
        } finally {
            conexion.cerrarConexion();
        }
        return cliente;
    }
    
    /**
     * Obtiene todos los paises existentes en la Base de Datos.
     * @return ArrayList de objetos de Ubicacion.
     */
    public static ArrayList<Ubicacion> listarPaises()throws AvwException {
        ArrayList<Ubicacion> paises = new ArrayList<Ubicacion>();
        StringBuilder sql = new StringBuilder();
        ConexionAvw conexion = new ConexionAvw();
        ResultSet rs;
        
        sql.append("SELECT ");
        sql.append("vdo_codigo, ");
        sql.append("vdo_significado ");
        sql.append("FROM valores_dominios ");
        sql.append("WHERE dom_codigo LIKE 'pais' ");
        sql.append(" order by vdo_significado");
        
        try {
            conexion.abrirConexion();
            rs = conexion.getPreparedStatementResultSet(sql, null);
            
            while (rs.next()) {
                Ubicacion ubicacion = new Ubicacion();
                
                ubicacion.setUbiCodigo(rs.getString("vdo_codigo"));
                ubicacion.setUbiNombre(rs.getString("vdo_significado"));
                
                paises.add(ubicacion);
            }
        } catch (SQLException e) {
            logger.log(Level.SEVERE,e.getMessage(),e);
            throw new AvwException(e);
        } finally {
            conexion.cerrarConexion();
        }
        
        return paises;
    }
    
    /**
     * Obtiene todas las provincias existentes en la Base de Datos.
     * @return ArrayList de objetos de Ubicacion.
     */
    public static ArrayList<Ubicacion> listarProvincias()throws AvwException {
        ArrayList<Ubicacion> provincias = new ArrayList<Ubicacion> ();
        StringBuilder sql = new StringBuilder();
        ConexionAvw conexion = new ConexionAvw();
        ResultSet rs;
        
        sql.append("SELECT ");
        sql.append("vdo_valor, ");
        sql.append("vdo_significado ");
        sql.append("FROM valores_dominios ");
        sql.append("WHERE dom_codigo LIKE 'provincias_cpa'");
        sql.append(" order by vdo_significado");
        
        logger.info(sql.toString());
        try {
            conexion.abrirConexion();
            rs = conexion.getPreparedStatementResultSet(sql, null);
            
            while (rs.next()) {
                Ubicacion ubicacion = new Ubicacion();
                
                ubicacion.setUbiCodigo(rs.getString("vdo_valor"));
                ubicacion.setUbiNombre(rs.getString("vdo_significado"));
                
                provincias.add(ubicacion);
            }
        } catch (SQLException e) {
            logger.log(Level.SEVERE,e.getMessage(),e);
            throw new AvwException(e);
        } finally {
            conexion.cerrarConexion();
        }
        
        return provincias;
    }
    
    /**
     * Obtiene todas las localidades, de la provincia pasada por parametro,
     * existentes en la Base de Datos.
     * @return ArrayList de objetos de Ubicacion.
     * @param  provincia Ubicacion (con codigo provincia solamente).
     */
    public static ArrayList<Ubicacion> listarLocalidades(Ubicacion provincia)throws AvwException {
        ArrayList<Ubicacion> localidades = new ArrayList<Ubicacion> ();
        StringBuilder sql = new StringBuilder();
        ConexionAvw conexion = new ConexionAvw();
        ArrayList params = new ArrayList();
        int pos = 0;
        ResultSet rs;
        
        sql.append("SELECT ");
        sql.append("loc_codigo, ");
        sql.append("loc_nombre, ");
        sql.append("pro_codigo ");
        sql.append("FROM ");
        sql.append("localidades_cpa ");
        sql.append("WHERE ");
        sql.append("pro_codigo = ? ");
        sql.append(" order by loc_nombre");
        params.add(new BoundParam(++pos,provincia.getUbiCodigo(),java.sql.Types.VARCHAR));
        
        try {
            conexion.abrirConexion();
            logger.info(sql.toString());
            rs = conexion.getPreparedStatementResultSet(sql, params);
            
            while (rs.next()) {
                Ubicacion ubicacion = new Ubicacion();
                
                ubicacion.setUbiCodigo(rs.getString("loc_codigo"));
                ubicacion.setUbiNombre(rs.getString("loc_nombre"));
                
                localidades.add(ubicacion);
            }
        } catch (SQLException e) {
            logger.log(Level.SEVERE,e.getMessage(),e);
            throw new AvwException(e);
        } finally {
            conexion.cerrarConexion();
        }
        
        return localidades;
    }
    
    /**
     * Insertar un cliente en el sistema.
     * @param  cliente Cliente.
     */
    public static void insertarCliente(Cliente cliente)throws AvwException {
        StringBuilder sqlNumerador = new StringBuilder();
        StringBuilder sql = new StringBuilder();
        ResultSet rs;
        String codigoObtenido = "";
        ConexionAvw conexion = new ConexionAvw();
        ArrayList params = new ArrayList();
        int pos = 0;
        
        /*Obtiene el valor de clientes en Numeradores*/
        /*sqlNumerador.append("SELECT num_valor ");
        sqlNumerador.append("FROM numeradores ");
        sqlNumerador.append("WHERE num_codigo LIKE 'clientes' ");
        */
        
        try {
            logger.info(sqlNumerador.toString());
            conexion.abrirConexion();
            conexion.startTransaction();
            /* rs = conexion.getPreparedStatementResultSet(sqlNumerador, null);
            
            /*Modifica numeradores incrementando en uno el valor de clientes*/
            /*rs.next();
            logger.info("Obtengo codigo");
            codigoObtenido = String.valueOf(rs.getInt("num_valor") + 1);
            logger.info("codigoObtenido : " + codigoObtenido);
            
            conexion.startTransaction();
            pos=0;
            sqlNumerador = new StringBuilder();
            sqlNumerador.append("UPDATE ");
            sqlNumerador.append("numeradores SET ");
            sqlNumerador.append("num_valor = ? ");
            sqlNumerador.append("WHERE num_codigo LIKE 'clientes' ");
            params.add(new BoundParam(++pos,codigoObtenido,java.sql.Types.NUMERIC));
            conexion.executePreparedStatement(sqlNumerador, params);*/
            
            /*Inserta el cliente con el numero obtenido*/
            sql.append("INSERT INTO ");
            sql.append("clientes (");
            //sql.append("cli_codigo, ");
            sql.append("cli_nombre, ");
            sql.append("cli_razon_social, ");
            sql.append("cli_direccion, ");
            sql.append("cli_piso, ");
            sql.append("cli_departamento, ");
            sql.append("cli_localidad, ");
            sql.append("cli_provincia, ");
            sql.append("cli_pais, ");
            sql.append("cli_codigo_postal, ");
            sql.append("cli_mail, ");
            sql.append("cli_ingresos_brutos, ");
            sql.append("cli_tipo_iva, ");
            sql.append("cli_cuit, ");
            sql.append("cli_fecha_alta ");
            sql.append(") ");
            sql.append("VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,sysdate) ");
            
            pos = 0;
            params.clear();
            //params.add(new BoundParam(++pos,codigoObtenido,java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliNombre(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliRazonSocial(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliDireccion(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliPiso(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliDepartamento(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliLocalidad().getUbiCodigo(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliProvincia().getUbiCodigo(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliPais().getUbiCodigo(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliCodigoPostal(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliEmail(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliIngresosBrutos(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliTipoIva(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliCuit(),java.sql.Types.VARCHAR));
            conexion.executePreparedStatement(sql, params);
            
            Recurso r = new Recurso("consultas.properties");
            
            sql.setLength(0);
            sql.append(r.obtenerPropiedad("consultaGetCliCodigo"));
            
            rs = conexion.getPreparedStatementResultSet(sql, null);
            rs.next();
            codigoObtenido = (String)rs.getString(1);
            
            sql.setLength(0);
            sql.append("INSERT INTO ");
            sql.append("cliente_web (");
            sql.append("cli_codigo, ");
            sql.append("clw_email, ");
            sql.append("clw_contrasenia ");
            sql.append(") ");
            sql.append("VALUES (?,?,?)");

            
            pos = 0;
            params.clear();
            params.add(new BoundParam(++pos,codigoObtenido,java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliEmail(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliContrasenia(),java.sql.Types.VARCHAR));
            
            conexion.executePreparedStatement(sql, params);
            conexion.commitTransaction();
        } catch (SQLException e) {
            try {
                conexion.rollbackTransaction();
            } catch (SQLException ex) {
                logger.log(Level.SEVERE,e.getMessage(),ex);
            }
            logger.log(Level.SEVERE,e.getMessage(),e);
            throw new AvwException(e,"clienteNoGuardado");
        } finally {
            conexion.cerrarConexion();
        }
        
    }
    
    /**
     * Modificar un cliente en el sistema.
     * @param  cliente Cliente.
     */
    public static void modificarCliente(Cliente cliente)throws AvwException {
        StringBuilder sql = new StringBuilder();
        ResultSet rs;
        ConexionAvw conexion = new ConexionAvw();
        ArrayList params = new ArrayList();
        int pos = 0;
        
        try {
            sql.append("UPDATE ");
            sql.append("clientes ");
            sql.append("SET ");
            sql.append("cli_nombre = ?");
            sql.append(", cli_razon_social = ?");
            sql.append(", cli_direccion = ?");
            sql.append(", cli_piso = ?");
            sql.append(", cli_departamento = '");
            sql.append(", cli_localidad = ?");
            sql.append(", cli_provincia = ?");
            sql.append(", cli_pais = ?");
            sql.append(", cli_codigo_postal = ?");
            sql.append(", cli_mail = ?");
            sql.append(", cli_ingresos_brutos = ?");
            sql.append(", cli_tipo_iva = '");
            sql.append(", cli_cuit = ?");
            sql.append(" WHERE ");
            sql.append(" cli_codigo LIKE ? ");
            
            params.add(new BoundParam(++pos,cliente.getCliNombre(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliRazonSocial(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliDireccion(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliPiso(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliDepartamento(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliLocalidad().getUbiCodigo(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliProvincia().getUbiCodigo(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliPais().getUbiCodigo(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliCodigoPostal(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliEmail(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliIngresosBrutos(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliTipoIva(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliCuit(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliCodigo(),java.sql.Types.VARCHAR));
            
            conexion.abrirConexion();
            conexion.executePreparedStatement(sql, params);
            
            sql = new StringBuilder();
            sql.append("UPDATE ");
            sql.append("cliente_web ");
            sql.append("SET ");
            sql.append("clw_email = ?");
            sql.append(", clw_contrasenia = ?");
            sql.append(" WHERE ");
            sql.append(" cli_codigo LIKE ?");
            
            pos = 0;
            params.clear();
            params.add(new BoundParam(++pos,cliente.getCliEmail(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliContrasenia(),java.sql.Types.VARCHAR));
            params.add(new BoundParam(++pos,cliente.getCliCodigo(),java.sql.Types.VARCHAR));
            
            conexion.executePreparedStatement(sql, params);
        } catch (SQLException e) {
            logger.log(Level.SEVERE,e.getMessage(),e);
            throw new AvwException(e,"clienteNoGuardado");
            
        } finally {
            conexion.cerrarConexion();
        }
        
    }
    
    /**
     * Obtiene el cliente cuyo codigo de cliente es el pasado por parametro.
     * @return objeto Cliente.
     * @param  cliente Cliente (con el codigo).
     */
    public static Cliente obtenerCliente(Cliente cliente) throws AvwException {
        StringBuilder sql = new StringBuilder();
        ResultSet rs;
        ConexionAvw conexion = new ConexionAvw();
        ArrayList params = new ArrayList();
        int pos = 0;
        
        sql.append("SELECT ");
        sql.append("c.cli_codigo, ");
        sql.append("c.cli_nombre, ");
        sql.append("c.cli_razon_social, ");
        sql.append("c.cli_direccion, ");
        sql.append("c.cli_piso, ");
        sql.append("c.cli_departamento, ");
        sql.append("c.cli_localidad, ");
        sql.append("c.cli_provincia, ");
        sql.append("c.cli_pais, ");
        sql.append("c.cli_codigo_postal, ");
        sql.append("c.cli_mail, ");
        sql.append("c.cli_ingresos_brutos, ");
        sql.append("c.cli_tipo_iva, ");
        sql.append("c.cli_cuit, ");
        sql.append("cw.clw_email, ");
        sql.append("cw.clw_contrasenia ");
        sql.append("FROM clientes c, cliente_web cw ");
        sql.append("WHERE c.cli_codigo = cw.cli_codigo ");
        sql.append("AND c.cli_codigo LIKE ?");
        params.add(new BoundParam(++pos,cliente.getCliCodigo(),java.sql.Types.VARCHAR));
        
        System.out.println(sql);        
        try {
            conexion.abrirConexion();
            rs = conexion.getPreparedStatementResultSet(sql, params);
            
            if (rs.next()) {
                cliente.setCliCodigo(rs.getString("cli_codigo"));
                cliente.setCliNombre(rs.getString("cli_nombre"));
                cliente.setCliRazonSocial(rs.getString("cli_razon_social"));
                cliente.setCliDireccion(rs.getString("cli_direccion"));
                cliente.setCliPiso(rs.getString("cli_piso"));
                cliente.setCliDepartamento(rs.getString("cli_departamento"));
                cliente.setCliLocalidad(new Ubicacion(rs.getString("cli_localidad")));
                cliente.setCliProvincia(new Ubicacion(rs.getString("cli_provincia")));
                cliente.setCliPais(new Ubicacion(rs.getString("cli_pais")));
                cliente.setCliCodigoPostal(rs.getString("cli_codigo_postal"));
                cliente.setCliIngresosBrutos(rs.getString("cli_ingresos_brutos"));
                cliente.setCliTipoIva(rs.getString("cli_tipo_iva"));
                cliente.setCliCuit(rs.getString("cli_cuit"));
                cliente.setCliEmail(rs.getString("clw_email"));
                cliente.setCliContrasenia(rs.getString("clw_contrasenia"));
            }
            
        } catch (SQLException e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
            throw new AvwException(e);
        } finally {
            conexion.cerrarConexion();
        }
        
        return cliente;
    }
}
